package com.zhengjiang.hl7;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.protocol.ReceivingApplication;
import ca.uhn.hl7v2.protocol.ReceivingApplicationException;

import java.util.Map;

import ca.uhn.hl7v2.model.*;
import ca.uhn.hl7v2.util.Terser;

import java.io.IOException;
import java.util.*;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class MyReceivingApplication implements ReceivingApplication {

//    private  JdbcConnectionsPool pool = new JdbcConnectionsPool();
    public  MessageTpyeList messageTpyeList = new MessageTpyeList();

    public MyReceivingApplication() throws SQLException {

      /*  String sql = "SELECT * FROM `view_hl7_map` ";//SQL语句
        Connection conn = pool.getConnection();
        Statement st = conn.createStatement();
        ResultSet resultSet = null;
        resultSet = st.executeQuery(sql);
        List<String[]> list = new ArrayList<>();
        while(resultSet.next())
        {
            String messageType=resultSet.getString("message_type");
            String tableTame = resultSet.getString("table_name");
            String tableFieldName = resultSet.getString("table_field_name");
            String hl7FieldName = resultSet.getString("hl7_field_name");
            messageTpyeList.add(messageType,tableTame,tableFieldName,hl7FieldName);
        }
        release(conn,st,resultSet);*/
    }


    @Override
    public Message processMessage(Message message, Map<String, Object> map) throws ReceivingApplicationException, HL7Exception {
        message.printStructure();

        Terser terser = new Terser(message);

        String messageID= map.get("/MSH-10").toString();
        String messageType = message.getName();
        String SendIP = map.get("SENDING_IP").toString();
        String SendPort = map.get("SENDING_PORT").toString();
        String rawMessage = map.get("raw-message").toString();
        System.out.println(messageID + "-"+messageID);
//        String rawMessageSql = "INSERT INTO `raw_hl7_message`(`messageType`, `messageID`, `SendIP`, `SendPort`,`rawMessage`)\n" +
//                " VALUES ('"+messageType+"', '"+messageID+"', '"+SendIP+"', '"+SendPort+"','"+rawMessage+"');";
//        for (MessageTypeAndTableList messageTypeAndTableList:messageTpyeList.list){
//            if(messageType.equals(messageTypeAndTableList.messageTypeName)){
//                for(TableNameAndFieldMap tableNameAndFieldMap:messageTypeAndTableList.list){
//                    getResultList(message, tableNameAndFieldMap);
//                }
//            }
//        }
//        messageTpyeList.getSQLList();
        Message message1 = null;
        try {
//            Connection conn = pool.getConnection();
//            Statement st = conn.createStatement();
//            st.execute(rawMessageSql);
//            for (String string :messageTpyeList.sqlList){
//                System.out.println(string);
////                st.execute(string);
//            }
            message1 = message.generateACK();

//            conn.close();
//            st.close();
        } catch (IOException e) {
            e.printStackTrace();
        }/* catch (SQLException e) {
            e.printStackTrace();
        }*/
        return message1;
    }

    @Override
    public boolean canProcess(Message message) {
        return true;
    }

    private void getResultList(Structure structurePara, TableNameAndFieldMap tableNameAndFieldMap) throws HL7Exception {
        if (!structurePara.isEmpty()) {
            if (Group.class.isAssignableFrom(structurePara.getClass())) {
                Group group = (Group) structurePara;
                for (String childrenStructName : group.getNames()) {
                    Structure[] structures = group.getAll(childrenStructName);
                    for (Structure structure : structures) {
                        if (!structure.isEmpty()) {
                            getResultList(structure, tableNameAndFieldMap);
                        }
                    }
                }
            } else if (!AbstractGroup.class.isAssignableFrom(structurePara.getClass())) {
                if (Segment.class.isAssignableFrom(structurePara.getClass())) {

                    Segment seg = (Segment) structurePara;
                    String segmentName = seg.getName();

                    if (tableNameAndFieldMap.inSegmentNameSet(segmentName)) {

                        List<String> segmentFieldLlist = tableNameAndFieldMap.segmentNameAndIndexMap.get(segmentName);
                        for (String segmentField : segmentFieldLlist) {
                            if (tableNameAndFieldMap.isInSegmentFieldStack(segmentField)) {
                                tableNameAndFieldMap.updateStackAandResult(segmentField);
                            }
                            int[] index = tableNameAndFieldMap.hl7_index_map.get(segmentField);
                            String hl7FieldValue = getHl7FieldValue(seg, index);
                            tableNameAndFieldMap.setSegmentFieldResult(segmentField, hl7FieldValue);
                        }
                        int l = seg.numFields();
                    }
                }
            }
        }

        if (Message.class.isAssignableFrom(structurePara.getClass())) {
            tableNameAndFieldMap.updateStackAandResult();
        }
    }

    private String getHl7FieldValue(Segment seg, int[] index) throws HL7Exception {

        String value = null;
        int[] subIndex = new int[index.length - 1];
        for (int i = 0; i < subIndex.length; i++) {
            subIndex[i] = index[i + 1];
        }
        Type[] type = seg.getField(index[0]);

        if(null == type || type.length <= 0 ){
            return "";
        }
        value = getTypeValue(type[0], subIndex);
        return value;
    }

    private String getTypeValue(Type type, int[] index) {

        String resultValue = null;
        if (type instanceof Primitive) {
            Primitive primitive = (Primitive) type;
            resultValue = primitive.getValue();
        } else if (type instanceof Composite) {

            Composite composite = (Composite) type;
            Type[] types = composite.getComponents();
            int[] subIndex = new int[index.length - 1];
            for (int i = 0; i < subIndex.length; i++) {
                subIndex[i] = index[i + 1];
            }
            resultValue = getTypeValue(types[index[0] - 1], subIndex);
        }else if(type instanceof Varies){
            Varies varies = (Varies)type;
            try {
                resultValue = varies.encode();
            } catch (HL7Exception e) {
                e.printStackTrace();
            }
        }
        return resultValue;
    }


    public static void release(Connection conn, Statement st, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (st != null) {
            try {
                st.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
